package generic;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 模拟一个需要定义的泛型
 */
class User {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

/**
 * 根据泛型获取类的实例
 * User限定泛型范围,可以定义为一个抽象类或接口
 *
 * @param <T>
 */
class Generic_02<T extends User> {

    public T data;

    /**
     * 构造函数
     */
    public Generic_02() {
        try {
            getInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void getInstance() throws IllegalAccessException, InstantiationException {
        //getClass().getGenericSuperclass()返回表示此 Class 所表示的实体（类、接口、基本类型或 void）的直接超类的 Type。
        Type type = getClass().getGenericSuperclass();

        //ParameterizedType表示参数化类型,具有<>符号的变量是参数化类型
        //也就是判断此类是不是一个泛型类
        if (type instanceof ParameterizedType) {
            System.out.println("此类是一个泛型类,可以进行下一步操作了");

            //拿到泛型表示的具体类型
            Class<T> tClass = (Class<T>) ((ParameterizedType) type).getActualTypeArguments()[0];

            //打印泛型类型
            System.out.println(tClass.getName());

            //获取实例
            data = tClass.newInstance();

            //因为限定了泛型的范围,所以可以使用公用的一些方法
            data.setName("Zhang");
            data.setAge(18);
            System.out.println("姓名:" + data.getName() + "\n年龄:" + data.getAge());
        }
    }
}

/**
 * 测试一下
 */
class TestClass extends Generic_02<User> {

    public static void main(String[] args) {
        new TestClass();
    }
}